<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  手写class

  <!-- class和构造函数的区别 -->
  1.class不能变量提升
  2.class只能通过new实例
  3.class是采用严格模式
  4.clas的原型上的属性不能遍历
  5.在class内部不能修改class的名称

  <script>
    /* 
    class Person {
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }

      say() {
        console.log('hello');
      }
      sayHi() {
        console.log('Hi');
      }
      static eat() {
        console.log('eat');
      }
    } 
    */

    // 手撕上述class类

    function Person(name, age) {
      "use strict"
      var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : name;
      var age = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : age;

      classCheck(this, Person); // 直通通过new实例
      this.name = name;
      this.age = age;
    }

    var createClass = (function () {
      function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
          var descriptor = props[i]
          descriptor.enumerable = descriptor.enumerable || false
          descriptor.configurable = descriptor.configurable || true

          Object.defineProperty(target, descriptor.key, descriptor)
        }
      }

      return function (constructor, protoProps, staticProps) {
        if (protoProps) defineProperties(constructor.prototype, protoProps)
        if (staticProps) defineProperties(constructor, staticProps)
      }
    })()

    createClass(Person, [
      {
        key: 'say',
        value: function () {
          console.log('hello');
        }
      },
      {
        key: 'sayHi',
        value: function () {
          console.log('Hi');
        }
      }
    ], [
      {
        key: 'eat',
        value: function () {
          console.log('eat');
        }
      }
    ])

    let p = new Person('zhangsan', 12)
    console.log(p);
    p.say()
    for (let i in p) {
      console.log(i);
    }
    function classCheck(instance, constructor) {
      // if (typeof new.target === undefined) {
      //   throw new Error('必须通过new执行')
      // }

      if (!(instance instanceof constructor)) {
        throw new Error('必须通过new执行')
      }
    }




  </script>
</body>

</html>